只剩下最後一部,今天我們終於要把一個題目給解決了~
寫到第三天,各位會不會覺得自己每天只討論這麼小的部分,三天才解完一題,幫助好像不大呢?
前陣子看到一篇前輩的就職半年心得 (剛剛本來想找原文,但臨時遍尋不到QAQ,找到之後一定來分享)
裡面就有提到一個讓我印象最深刻的地方:
她們公司主管每一陣子就會安排一個小小的技術題目,讓大家深入探討與解答,
「每天要遇到的技術規格很龐大,讓人忘記了,每一個複雜技術的背後,都是由這些小小的疑問所累積起來的。」
對我來說,寫一篇鐵人賽文章要花費的時間頂多是一到一個半小時,專注在一個看似超小的細節,
但光是用我覺得最白話、最易懂的方式搞懂一個觀念,加深自己的印象,未來就更能朝向複雜的問題去克服了。
(老實跟大家說,我現在連 LeetCode easy 一題都解不出來,還是找到了一份 junior 前端的工作XD)
(代表 LeetCode Easy 還是太難了)(誤)
閒聊結束了,那就讓我們把這個題目完成吧!
接續昨天的,我重貼一次題目與程式碼
try {
throw new Error();
}catch(x){
var x = 'X'
var y = 'Y'
const z = 'Z'
console.log(`${x} is in the catch`)
console.log(`${y} is in the catch`)
console.log(`${z} is in the catch`)
}
console.log(`${x} is outside the catch`)
console.log(`${y} is outside the catch`)
console.log(`${z} is outside the catch`)
首先在 Day1,我們了解到由於 try...catch 例外處理的執行流程,六個 console.log 執行的順序會從 catch 區塊,依序由上而下,進行到下方的外部區塊。
接著在 Day2,我們了解到由於變數的特性,所以會有提升、作用域的限制、重新賦值的特性。
於是略過 console.log(${x} is outside the catch
) 這條之外,我們所知的執行結果將會是:
X is in the catch
Y is in the catch
Z is in the catch
// 略過,等等來討論!
Y is outside the catch
Uncaught ReferenceError: z is not defined
好的,那就讓我們開始來討論 console.log(${x} is outside the catch
) 這一條到底會是什麼執行結果囉~
好的,來到壓軸的單元了,為什麼明明 x 跟 y 都是 var 變數、都放在一樣的位置,但這邊要故意拉出來談,陷阱到底是什麼?
(為什麼呢?)
不賣關子了,大家看到這個標題應該就知道提示很明顯了,沒錯,因為 catch() 中我們傳入了 x。
通常在 try...catch 的語句中, 我們會在 catch()中放入一個 error 參數,也就是一個代表錯誤訊息的物件,而 error 也可以是一個自訂的變數名稱,通常都會寫成 e 或是 error。
重新複習一次,程式碼在 try 區塊拋出錯誤後會暫停、並進入 catch 區塊執行,並針對錯誤狀況做處理,
例如:
try {
// 嘗試執行會拋出錯誤的程式碼
throw new Error();
} catch (error) {
// 處理錯誤
console.error("An error occurred:", error.message);
}
所以當我們把 x 作為參數傳入 catch()區塊,X 實際上是被當作 error 物件。
我們先不要在 catch 區域為 x 賦值,先把 x 作為 error 物件印出結果看看:
try {
throw new Error();
}catch(x){
console.log(x) // Error:
}
此時,當我們不在 catch 區塊為 error 物件賦值的話,就會看到輸出空白的 Error: ,如果我們將 throw new Error()
改成 throw new Error('This is a custom error mesage')
,就會看到 console.log(x)
輸出的訊息為 Error: This is a custom error message
,這就是我們為 error 物件給予一個錯誤訊息的結果。
try {
throw new Error('This is a custom error mesage')
}catch(x){
// 先註解掉 x = 'X
console.log(x) // Error: This is a custom error message
}
而當我們在 catch 為 error 物件用 = 來賦值,就會把原本物件的值蓋掉。
所以乍看之下,x 與 y 是一樣的,但 x 在 catch 區域中被當作一個錯誤物件,所以當我們在 catch 以外嘗試存取 x 時,只會收到 undefined 的結果。
var x; // var 變數被提升到外部,此時若存取 x 變數將獲得 undefined
try {
throw new Error();
}catch(x){
// 在 catch 區塊, x 跟外面的 var x 無關,並不會影響 var x,而是代表一個錯誤物件
x = 'X'
console.log(`${x} is in the catch`) // 覆蓋錯誤物件 x 的值
}
console.log(`${x} is outside the catch`) // undefined
於是,我們終於能夠回答這個題目的答案了!
請問下列程式碼執行結果為何?
try {
throw new Error();
}catch(x){
var x = 'X'
var y = 'Y'
const z = 'Z'
console.log(`${x} is in the catch`)
console.log(`${y} is in the catch`)
console.log(`${z} is in the catch`)
}
console.log(`${x} is outside the catch`)
console.log(`${y} is outside the catch`)
console.log(`${z} is outside the catch`)
執行結果依序是:
X is in the catch
Y is in the catch
Z is in the catch
undefined is outside the catch
Y is outside the catch
Uncaught ReferenceError: z is not defined
歐耶!完成!
我解答完一個把我考倒的面試題目了~
今天沒有把細節探討到太深,如果沒有說得很詳盡的地方,歡迎大家幫忙補充,之後我也會再多補充一些資料!
那我們 Day4 見~
參考資料:
MDN: try...catch 語法